#ifndef COMMUNICATOR_H
#define COMMUNICATOR_H

#include <SFML/Network.hpp>
#include <QDebug>
#include <QStack>
#include <QTimer>

#include "MassagesTypes.h"
#include "sfmlWindow.h"

#define MAX_PLAYERS         10
#define SERVER_PORT         55001
#define START_LIFETIME      5000
#define UPDATE_LIFETIME     34


class Communicator : public QObject
{
    Q_OBJECT

    struct Msg {

        sf::IpAddress   ip;
        sf::Uint16      port;
        sf::Packet      msg;

        Msg(sf::IpAddress ip, sf::Uint16 port, sf::Packet msg) :
            ip(ip), port(port), msg(msg) {}
    };


    std::vector<plInLobby> list;

    bool                amIServer;
    bool                inLobby;

    sf::IpAddress       serv_ip;
    double              srv_lifetime;

    sf::IpAddress       my_ip;
    sf::Uint16          my_port;

    sf::IpAddress       str_ip;

    short               id_count;

    QString             name;
    sf::UdpSocket       udpSocket;

    sf::SocketSelector  selector;

    QStack<Msg*>        outStack;
    QStack<Msg*>        inStack;

    std::vector<Host>   serverList;

    SFMLWindow*         sfml;

public:

    explicit    Communicator(SFMLWindow* sf, QObject *parent = 0);

    QTimer* slotTimer;
    QTimer* lifeTimer;

    bool isServer();

    void addMsgToStack(sf::IpAddress, sf::Uint16 port, sf::Packet);
    void addServerToList(Host host);

    void askConnectionToServer(sf::IpAddress);
    void askServerInfo(sf::IpAddress);

    void sendServInfo(sf::IpAddress, sf::Uint16 port);
    void broadcastMsg(sf::IpAddress, sf::Uint16 port, QString);

    void checkInStack();
    void checkOutStack();

    bool addPlayer(sf::IpAddress ip, sf::Uint16 port);
    void solveName(sf::IpAddress ip, sf::Uint16, QString nm);

    QString     getPlayerName(sf::IpAddress ip, sf::Uint16 port);
    void        lifeUpPlayer(sf::IpAddress ip, sf::Uint16 port);
    void        playShoots();

public slots:
    void checkSocket();
    void becomeServer(bool);
    void refreshServerList();
    void changeName(const QString & text);
    void changeStrIp(const QString & text);
    void tryToConnect(sf::IpAddress);
    void strConnection();
    void chatMsg(QString msg);
    void updateLifetime();

    void broadcastPlList();
    void broadcastColors();
    void checkNames();

    void leaveGame();
    void startGame();
    void gameLoop();

    void sendShoot(shoot sh);

signals:
    void consoleOut(QString str, Qt::GlobalColor brush);
    void statusOut(QString str);
    void servListChanged(std::vector<Host>* list);
    void playerListChanged(std::vector<plInLobby>* list);
    void comeToLobby();
    void comeToGame();
    void leaveLobby();
    void colorChanged(sf::Int16);
    void tankOut(tankInfo tank);
    void startGameSignal();


};

#endif // COMMUNICATOR_H
